package com.example.hello.service.impl;

import com.example.hello.mapper.BookMapper;
import com.example.hello.mapper.InteractionMapper;
import com.example.hello.pojo.Book;
import com.example.hello.pojo.Interaction;
import com.example.hello.recommender.CFRecommender;
import com.example.hello.recommender.dto.BookRecommendationDTO;
import com.example.hello.service.RecommendationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class RecommendationServiceImpl implements RecommendationService {

    @Autowired
    private InteractionMapper interactionMapper;
    
    @Autowired
    private BookMapper bookMapper;

    /**
     * 从数据库中获取所有图书ID，实际应从 book 表中查询
     */
    public List<Integer> getAllBookIds() {
        // 此示例简单采用从用户行为中获取所有参与过评分的书籍ID，
        // 实际建议直接查询 Book 表得到所有图书ID
        List<Interaction> interactions = interactionMapper.getAllInteractions();
        return interactions.stream()
                .map(Interaction::getBookId)
                .distinct()
                .collect(Collectors.toList());
    }

    /**
     * 生成目标用户的推荐列表，并返回包含图书详情的DTO对象
     */
    public List<BookRecommendationDTO> recommendBooks(Integer userId, int topN) {
        List<Interaction> interactions = interactionMapper.getAllInteractions();
        if (interactions == null || interactions.isEmpty()) {
            return Collections.emptyList();
        }
        CFRecommender recommender = new CFRecommender(interactions);
        List<Integer> allBookIds = getAllBookIds();
        List<Map.Entry<Integer, Double>> recEntries = recommender.recommendBooks(userId, allBookIds, topN);
        
        List<BookRecommendationDTO> dtos = new ArrayList<>();
        for (Map.Entry<Integer, Double> entry : recEntries) {
            Book book = bookMapper.getBookById(entry.getKey());
            if (book != null) {
                dtos.add(new BookRecommendationDTO(book, entry.getValue()));
            }
        }
        return dtos;
    }
}